using System.Runtime.CompilerServices;
using System.Collections.Generic;

//
// * Copyright (c) 2002-2009 "Neo Technology,"
// *     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// * This file is part of Neo4j.
// * 
// * Neo4j is free software: you can redistribute it and/or modify
// * it under the terms of the GNU Affero General Public License as
// * published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version.
// * 
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU Affero General Public License for more details.
// * 
// * You should have received a copy of the GNU Affero General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.kernel.impl.transaction
{


	using XAResource = javax.transaction.xa.XAResource;
	using Xid = javax.transaction.xa.Xid;

	internal class FakeXAResource : XAResource
	{
		private string name = null;
		private int transactionTimeout = 0;
		private List<MethodCall> methodCalls = new List<MethodCall>();

		internal FakeXAResource(string name)
		{
			this.name = name;
		}

		public virtual string Name
		{
			get
			{
				return name;
			}
		}

		public override string ToString()
		{
			return name;
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		internal virtual MethodCall[] getAndRemoveMethodCalls()
		{
			if (methodCalls.Count > 0)
			{
				MethodCall[] methodCallArray = new MethodCall[methodCalls.Count];
				methodCallArray = methodCalls.ToArray(methodCallArray);
				methodCalls = new List<MethodCall>();
				return methodCallArray;
			}
			return new MethodCall[0];
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		private void addMethodCall(MethodCall methodCall)
		{
			methodCalls.Add(methodCall);
		}

		public virtual void commit(Xid xid, bool onePhase)
		{
			addMethodCall(new MethodCall("commit", new object[] { xid, new bool(onePhase) }, new string[] { "javax.transaction.xa.Xid", "java.lang.Boolean" }));
		}

		public virtual void end(Xid xid, int flags)
		{
			addMethodCall(new MethodCall("end", new object[] { xid, new int(flags) }, new string[] { "javax.transaction.xa.Xid", "java.lang.Integer" }));
		}

		public virtual void forget(Xid xid)
		{
			addMethodCall(new MethodCall("forget", new object[] { xid }, new string[] { "javax.transaction.xa.Xid" }));
		}

		public virtual int getTransactionTimeout()
		{
			return transactionTimeout;
		}

		public virtual bool setTransactionTimeout(int timeout)
		{
			transactionTimeout = timeout;
			return true;
		}

		public virtual bool isSameRM(XAResource xares)
		{
			if (xares is FakeXAResource)
			{
				if (this.name.Equals(((FakeXAResource) xares).Name))
				{
					return true;
				}
			}
			return false;
		}

		public virtual int prepare(Xid xid)
		{
			addMethodCall(new MethodCall("prepare", new object[] { xid }, new string[] { "javax.transaction.xa.Xid" }));
			return XAResource.XA_OK;
		}

		public virtual Xid[] recover(int flag)
		{
			addMethodCall(new MethodCall("recover", new object[] { new int(flag) }, new string[] { "java.lang.Integer" }));
			return new Xid[0];
		}

		public virtual void rollback(Xid xid)
		{
			addMethodCall(new MethodCall("rollback", new object[] { xid }, new string[] { "javax.transaction.xa.Xid" }));
		}

		public virtual void start(Xid xid, int flags)
		{
			addMethodCall(new MethodCall("start", new object[] { xid, new int(flags) }, new string[] { "javax.transaction.xa.Xid", "java.lang.Integer" }));
		}
	}
}